package io.github.talelin.latticy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.github.talelin.autoconfigure.exception.ForbiddenException;
import io.github.talelin.autoconfigure.exception.NotFoundException;
import io.github.talelin.latticy.common.LocalUser;
import io.github.talelin.latticy.common.mybatis.Page;
import io.github.talelin.latticy.dto.warehouse.UpdateWareDTO;
import io.github.talelin.latticy.dto.warehouse.WarehouseDTO;
import io.github.talelin.latticy.model.UserDO;
import io.github.talelin.latticy.model.WarehouseDO;
import io.github.talelin.latticy.mapper.WarehouseMapper;
import io.github.talelin.latticy.service.AreaService;
import io.github.talelin.latticy.service.GroupService;
import io.github.talelin.latticy.service.UserwareService;
import io.github.talelin.latticy.service.WarehouseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.github.talelin.latticy.util.IdUtil;
import io.github.talelin.latticy.vo.WarehouseVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * <p>
 * 仓库 服务实现类
 * </p>
 *
 * @author generator@wulongbo
 * @since 2022-05-10
 */
@Service
public class WarehouseServiceImpl extends ServiceImpl<WarehouseMapper, WarehouseDO> implements WarehouseService {

    @Autowired
    private AreaService areaService;

    @Autowired
    private GroupService groupService;

    @Override
    public WarehouseDO createWarehouse(WarehouseDTO dto) {
        boolean exist = this.checkWarehouseExistByName(dto.getName());
        if (exist) {
            throw new ForbiddenException(18300);
        }
        if (StringUtils.isEmpty(dto.getCode())) {
            dto.setCode(IdUtil.getLowercaseAndUppercaseLettersAndNumber(5));
        }
        WarehouseDO warehouse = new WarehouseDO(dto);
        this.baseMapper.insert(warehouse);
        return warehouse;
    }

    @Override
    public boolean updateWarehouse(String code, UpdateWareDTO dto) {
        Optional.ofNullable(dto.getName()).ifPresent(this::checkWarehouseExistByNameOptional);
        WarehouseDO warehouse = new WarehouseDO(code, dto);
        return this.baseMapper.updateById(warehouse) > 0;
    }

    @Override
    public WarehouseDO getWarehouseByCode(String code) {
        WarehouseDO warehouseDO = this.baseMapper.selectById(code);
        Optional.ofNullable(warehouseDO).orElseThrow(() -> new NotFoundException(18301));
        return warehouseDO;
    }

    @Override
    public IPage<WarehouseDO> getWarePage(Integer page, Integer count) {
        Page<WarehouseDO> pager = new Page<>(page, count);
        return this.baseMapper.selectPage(pager, null);
    }

    @Override
    public List<WarehouseDO> getWareList() {
        UserDO userDO = LocalUser.getLocalUser();
        boolean admin = groupService.checkIsRootByUserId(userDO.getId());
        if (admin) {
            QueryWrapper<WarehouseDO> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(WarehouseDO::getStatus, 1);
            return this.baseMapper.selectList(wrapper);
        }
        return this.baseMapper.getWarehouseListByUserId(userDO.getId());
    }

    @Override
    public boolean checkWarehouseExistByCode(String code) {
        int rows = this.baseMapper.selectCountByCode(code);
        return rows > 0;
    }

    @Override
    public boolean checkWarehouseExistByName(String username) {
        int rows = this.baseMapper.selectCountByName(username);
        return rows > 0;
    }

    @Override
    public boolean checkWarehouseExistByEmail(String email) {
        QueryWrapper<WarehouseDO> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(WarehouseDO::getEmail, email);
        int rows = this.baseMapper.selectCount(wrapper);
        return rows > 0;
    }

    @Override
    public int getWarehouseCountByWareCodes(List<String> wareCodes) {
        QueryWrapper<WarehouseDO> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(WarehouseDO::getCode, wareCodes);
        return this.baseMapper.selectCount(wrapper);
    }

    @Override
    public List<WarehouseVO> getAllWarehouseByOmsRoot() {
        return baseMapper.getAllWarehouseByOmsRoot();
    }

//    private void checkAreaByIds(WarehouseDTO dto) {
//        areaService.checkAreaExistByAreaId(dto.getAreaId());
//        areaService.checkAreaExistByProvinceId(dto.getProvince());
//        areaService.checkAreaExistByCityIdId(dto.getCity());
//    }

    private void checkWarehouseExistByNameOptional(String name) {
        boolean exist = this.checkWarehouseExistByName(name);
        if (exist) {
            throw new ForbiddenException(18300);
        }
    }
}
